home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / Sources / FWPrInfo.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  33.6 KB  |  1,341 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWPrInfo.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWPRINFO_H
  13. #include "FWPrInfo.h"
  14. #endif
  15.  
  16. #ifndef FWMEMORY_H
  17. #include "FWMemory.h"
  18. #endif
  19.  
  20. #ifndef FWBARRAY_H
  21. #include "FWBArray.h"
  22. #endif
  23.  
  24. #ifndef FWACQUIR_H
  25. #include "FWAcquir.h"
  26. #endif
  27.  
  28. #ifndef FWGXUTIL_H
  29. #include "FWGXUtil.h"
  30. #endif
  31.  
  32. #ifndef FWGRUTIL_H
  33. #include "FWGrUtil.h"
  34. #endif
  35.  
  36. #ifndef FWPRHDLR_H
  37. #include "FWPrHdlr.h"
  38. #endif
  39.  
  40. #ifndef FWSTRS_H
  41. #include "FWStrs.h"
  42. #endif
  43.  
  44. // ----- QuickDraw GX includes
  45.  
  46. #if defined(FW_SUPPORT_GX) && !defined(__GXGRAPHICS__)
  47. #include <GXGraphics.h>
  48. #endif
  49.  
  50. #if defined(FW_SUPPORT_GX) && !defined(__GXENVIRONMENT__)
  51. #include <GXEnvironment.h>
  52. #endif
  53.  
  54. // ----- OpenDoc includes
  55.  
  56. #ifndef SOM_ODSession_xh
  57. #include <ODSessn.xh>
  58. #endif
  59.  
  60. #ifndef SOM_ODArbitrator_xh
  61. #include <Arbitrat.xh>
  62. #endif
  63.  
  64. #ifndef SOM_ODFoci_xh
  65. #include <Foci.xh>
  66. #endif
  67.  
  68. #ifndef SOM_ODFrame_xh
  69. #include <Frame.xh>
  70. #endif
  71.  
  72. #ifndef SOM_ODWindowState_xh
  73. #include <WinStat.xh>
  74. #endif
  75.  
  76. #ifndef SOM_ODStorageUnit_xh
  77. #include <StorageU.xh>
  78. #endif
  79.  
  80. #ifndef SOM_ODCanvas_xh
  81. #include <Canvas.xh>
  82. #endif
  83.  
  84. #ifndef SOM_ODFacet_xh
  85. #include <Facet.xh>
  86. #endif
  87.  
  88. //========================================================================================
  89. // RunTime Info
  90. //========================================================================================
  91.  
  92. #ifdef FW_BUILD_MAC
  93. #pragma segment odfprinting
  94. #endif
  95.  
  96. FW_DEFINE_AUTO(FW_CPrintEnvironment)
  97. FW_DEFINE_AUTO(FW_CPrintInfo)
  98. FW_DEFINE_AUTO(FW_CPrintJob)
  99.  
  100. //========================================================================================
  101. // Local helpers
  102. //========================================================================================
  103.  
  104. static void    SaveHandle(
  105.             Environment*         ev,
  106.             ODStorageUnit*         storageUnit,
  107.             const char*            propName,
  108.             const char*            propType,
  109.             FW_PlatformHandle    handle);
  110.             
  111. static void    SaveBuffer(
  112.             Environment*         ev,
  113.             ODStorageUnit*         storageUnit,
  114.             const char*            propName,
  115.             const char*            propType,
  116.             const void*            buffer,
  117.             unsigned long        bufSize);
  118.             
  119. static FW_Boolean LoadHandle(
  120.             Environment*         ev,
  121.             ODStorageUnit*         storageUnit,
  122.             const char*            propName,
  123.             const char*            propType,
  124.             FW_PlatformHandle&    handle);
  125.  
  126. static FW_Boolean LoadBuffer(
  127.             Environment*         ev,
  128.             ODStorageUnit*         storageUnit,
  129.             const char*            propName,
  130.             const char*            propType,
  131.             void*                buffer,
  132.             unsigned long&        bufSize);
  133.  
  134. #if defined(FW_SUPPORT_GX) && defined(FW_BUILD_MAC)
  135.  
  136. static OSErr    MacGXSpoolProc(gxShape currentShape, long refCon);
  137.  
  138. struct SMacGXSpool
  139. {
  140.     gxViewPort        fGXViewPort;
  141.     gxJob            fGXPrintJob;
  142.     FW_CRect        fPageBounds;
  143. };
  144.  
  145. static SMacGXSpool        gMacGXSpool;
  146.  
  147. #endif
  148.  
  149. //========================================================================================
  150. // class FW_CPrintEnvironment
  151. //========================================================================================
  152.  
  153. //----------------------------------------------------------------------------------------
  154. // FW_CPrintEnvironment::FW_CPrintEnvironment
  155. //----------------------------------------------------------------------------------------
  156.  
  157. FW_CPrintEnvironment::FW_CPrintEnvironment()
  158. {
  159. #ifdef FW_SUPPORT_GX
  160.     if (!FW_IsGXInstalled())
  161.     {
  162. #endif
  163.  
  164. #ifdef FW_BUILD_MAC
  165.         ::PrOpen();                        // Open the current printer driver and resource file
  166.         
  167.         short error = ::PrError();
  168.         if (error == fnfErr)
  169.             FW_Failure(FW_xNoDefaultPrinter);
  170.         FW_FailOnError(error);
  171.  
  172.         fMacResFile = ::CurResFile();    // Save the driver's resource file
  173. #endif
  174.  
  175. #ifdef FW_SUPPORT_GX
  176.     }
  177. #endif
  178.  
  179. #ifdef FW_BUILD_MAC
  180.     ::GetPort(&fOldPort);
  181. #endif
  182.  
  183.     FW_END_CONSTRUCTOR
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. // FW_CPrintEnvironment::~FW_CPrintEnvironment
  188. //----------------------------------------------------------------------------------------
  189.  
  190. FW_CPrintEnvironment::~FW_CPrintEnvironment()
  191. {
  192.     FW_START_DESTRUCTOR
  193.  
  194. #ifdef FW_BUILD_MAC
  195.     ::SetPort(fOldPort);
  196. #endif
  197.  
  198. #ifdef FW_SUPPORT_GX
  199.     if (!FW_IsGXInstalled())
  200.     {
  201. #endif
  202.  
  203. #ifdef FW_BUILD_MAC
  204.         ::UseResFile(fMacResFile);
  205.         ::PrClose();
  206. #endif
  207.  
  208. #ifdef FW_SUPPORT_GX
  209.     }
  210. #endif
  211. }
  212.  
  213. #ifdef FW_BUILD_MAC
  214. //----------------------------------------------------------------------------------------
  215. // FW_CPrintEnvironment::MacRestoreResFile
  216. //----------------------------------------------------------------------------------------
  217.  
  218. void FW_CPrintEnvironment::MacRestoreResFile()
  219. {
  220.     ::UseResFile(fMacResFile);
  221. }
  222. #endif
  223.  
  224. //========================================================================================
  225. //    class FW_CPrintInfo
  226. //========================================================================================
  227.  
  228. const char*    kPrintInfoProp    =    "ODF:Property:PrintingInfo";
  229.  
  230. #ifdef FW_BUILD_WIN
  231. const char*    kPrintType        =    "Windows:Type:Print info";
  232. const char*    kTypeDevMode    =    "Windows:Type:DEVMODE";
  233. const char*    kTypeDevNames    =    "Windows:Type:DEVNAMES";
  234. #endif
  235.  
  236. #ifdef FW_BUILD_MAC
  237. const char*    kPrintType        =    "Macintosh:Type:TPrint Record";
  238. #endif
  239.  
  240. #ifdef FW_SUPPORT_GX
  241. const char*    kPrintTypeGX    =    "Macintosh:Type:QuickDrawGX Job";
  242. #endif
  243.  
  244. const int kMaxPage = 9999;
  245.  
  246. //----------------------------------------------------------------------------------------
  247. // FW_CPrintInfo::FW_CPrintInfo
  248. //----------------------------------------------------------------------------------------
  249.  
  250. FW_CPrintInfo::FW_CPrintInfo(
  251.         Environment*             ev,
  252.         ODStorageUnit*             storageUnit,
  253.         FW_CPrintEnvironment*    /* printEnv */)
  254. {
  255. #ifdef FW_BUILD_WIN
  256.     WinSetPrintDlgToDefaults();
  257. #endif
  258. #ifdef FW_SUPPORT_GX
  259.     fGXJob = NULL;
  260. #endif
  261. #ifdef FW_BUILD_MAC
  262.     fMacPrintRec = NULL;
  263. #endif
  264.  
  265.     // ----- Check for QuickDraw GX print job
  266.  
  267. #ifdef FW_SUPPORT_GX
  268.     if (FW_IsGXInstalled())
  269.     {
  270.         fGXJob = LoadFromStorageUnitGX(ev, storageUnit);
  271.         if (fGXJob != NULL)
  272.             return;
  273.     }
  274. #endif
  275.  
  276.     // ----- Check for platform print info structure
  277.  
  278. #ifdef FW_BUILD_WIN
  279.     unsigned long bufSize;
  280.     if (::LoadBuffer(ev, storageUnit, kPrintInfoProp, kPrintType, &fWinPrintDlg, bufSize))
  281.     {
  282.         ::LoadHandle(ev, storageUnit, kPrintInfoProp, kTypeDevMode, fWinPrintDlg.hDevMode);
  283.         ::LoadHandle(ev, storageUnit, kPrintInfoProp, kTypeDevNames, fWinPrintDlg.hDevNames);
  284.         return;
  285.     }
  286. #endif
  287.  
  288. #ifdef FW_BUILD_MAC
  289.     THPrint thPrint = NULL;
  290.     if (::LoadHandle(ev, storageUnit, kPrintInfoProp, kPrintType, (FW_PlatformHandle&) thPrint))
  291.     {
  292. #ifdef FW_SUPPORT_GX
  293.         if (FW_IsGXInstalled())
  294.         {
  295.             FW_XPrint::CheckPrintError(::GXNewJob(&fGXJob));
  296.              ::GXConvertPrintRecord(fGXJob, thPrint);
  297.             FW_CMemoryManager::FreeSystemHandle((FW_PlatformHandle)thPrint);
  298.             FW_XPrint::CheckGXJobError(fGXJob);
  299.             return;
  300.         }
  301. #endif
  302.  
  303.         fMacPrintRec = thPrint;
  304.  
  305.         ::PrValidate(fMacPrintRec);
  306.         FW_XPrint::MacCheckPrintError();
  307.  
  308.         return;
  309.     }
  310. #endif
  311.  
  312.         // ----- Create default print info structure
  313.         
  314. #ifdef FW_SUPPORT_GX
  315.     if (FW_IsGXInstalled())
  316.     {
  317.         FW_XPrint::CheckPrintError(::GXNewJob(&fGXJob));
  318.         return;
  319.     }
  320. #endif
  321.  
  322. #ifdef FW_BUILD_WIN
  323.     WinSetPrintDlgToDefaults();
  324. #endif
  325.  
  326. #ifdef FW_BUILD_MAC
  327.     fMacPrintRec = (THPrint) FW_CMemoryManager::AllocateSystemHandle(sizeof(TPrint));
  328.     ::PrintDefault(fMacPrintRec);
  329. #endif
  330.  
  331.     FW_END_CONSTRUCTOR
  332. }
  333.  
  334. #ifdef FW_SUPPORT_GX
  335. //----------------------------------------------------------------------------------------
  336. // FW_CPrintInfo::LoadFromStorageUnitGX
  337. //----------------------------------------------------------------------------------------
  338.  
  339. gxJob FW_CPrintInfo::LoadFromStorageUnitGX(
  340.         Environment* ev,
  341.         ODStorageUnit* storageUnit)
  342. {
  343.     gxJob job = NULL;
  344.     FW_PlatformHandle handle = NULL;
  345.     if (::LoadHandle(ev, storageUnit, kPrintInfoProp, kPrintTypeGX, handle))
  346.     {
  347.         ::GXNewJob(&job);
  348.         ::GXUnflattenJobFromHdl(job, handle);
  349.         FW_CMemoryManager::FreeSystemHandle(handle);
  350.         FW_XPrint::CheckGXJobError(job);
  351.     }
  352.  
  353.     return job;
  354. }
  355. #endif
  356.  
  357. //----------------------------------------------------------------------------------------
  358. // FW_CPrintInfo::~FW_CPrintInfo
  359. //----------------------------------------------------------------------------------------
  360.  
  361. FW_CPrintInfo::~FW_CPrintInfo()
  362. {
  363.     FW_START_DESTRUCTOR
  364.     
  365. #ifdef FW_SUPPORT_GX
  366.     if (fGXJob != NULL)
  367.         ::GXDisposeJob(fGXJob);
  368. #endif
  369.  
  370. #ifdef FW_BUILD_MAC
  371.     if(fMacPrintRec != NULL)
  372.         FW_CMemoryManager::FreeSystemHandle((FW_PlatformHandle)fMacPrintRec);
  373. #endif
  374. }
  375.  
  376. #ifdef FW_BUILD_WIN
  377. //----------------------------------------------------------------------------------------
  378. // FW_CPrintInfo::WinSetPrintDlgToDefaults
  379. //----------------------------------------------------------------------------------------
  380.  
  381. void FW_CPrintInfo::WinSetPrintDlgToDefaults()
  382. {
  383.     fWinPrintDlg.lStructSize            = sizeof(PRINTDLG);
  384.     fWinPrintDlg.hDevMode                = NULL;
  385.     fWinPrintDlg.hDevNames                = NULL;
  386.     fWinPrintDlg.Flags                    = 0;
  387.     fWinPrintDlg.hwndOwner                = NULL;
  388.     fWinPrintDlg.hDC                     = NULL;
  389.     fWinPrintDlg.nFromPage                = 1;
  390.     fWinPrintDlg.nToPage                = kMaxPage;
  391.     fWinPrintDlg.nMinPage                = 1;
  392.     fWinPrintDlg.nMaxPage                = kMaxPage;
  393.     fWinPrintDlg.nCopies                = 1;
  394.     fWinPrintDlg.hInstance                = NULL;
  395.     fWinPrintDlg.lCustData                = 0l;
  396.     fWinPrintDlg.lpfnPrintHook            = NULL;
  397.     fWinPrintDlg.lpfnSetupHook            = NULL;
  398.     fWinPrintDlg.lpPrintTemplateName    = NULL;
  399.     fWinPrintDlg.lpSetupTemplateName    = NULL;
  400.     fWinPrintDlg.hPrintTemplate            = NULL;
  401.     fWinPrintDlg.hSetupTemplate            = NULL;
  402. }
  403. #endif
  404.  
  405. //----------------------------------------------------------------------------------------
  406. // FW_CPrintInfo::SaveToStorageUnit
  407. //----------------------------------------------------------------------------------------
  408.  
  409. void FW_CPrintInfo::SaveToStorageUnit(Environment* ev, ODStorageUnit* storageUnit) const
  410. {
  411. #ifdef FW_SUPPORT_GX
  412.     if (fGXJob != NULL)
  413.     {
  414.         FW_PlatformHandle handle = FW_CMemoryManager::AllocateSystemHandle(0);
  415.         ::GXFlattenJobToHdl(fGXJob, handle);
  416.  
  417.         FW_TRY
  418.         {
  419.             ::SaveHandle(ev, storageUnit, kPrintInfoProp, kPrintTypeGX, handle);
  420.         }
  421.         FW_CATCH_BEGIN
  422.         FW_CATCH_EVERYTHING()
  423.         {
  424.             FW_CMemoryManager::FreeSystemHandle(handle);
  425.     
  426.             FW_THROW_SAME();
  427.         }
  428.         FW_CATCH_END
  429.  
  430.         FW_CMemoryManager::FreeSystemHandle(handle);
  431.         return;
  432.     }
  433. #endif
  434.  
  435. #ifdef FW_BUILD_WIN
  436.     ::SaveBuffer(ev, storageUnit, kPrintInfoProp, kPrintType, &fWinPrintDlg, sizeof fWinPrintDlg);
  437.     
  438.     ::SaveHandle(ev, storageUnit, kPrintInfoProp, kTypeDevNames, fWinPrintDlg.hDevNames);
  439.     ::SaveHandle(ev, storageUnit, kPrintInfoProp, kTypeDevMode, fWinPrintDlg.hDevMode);
  440. #endif
  441. #ifdef FW_BUILD_MAC
  442.     ::SaveHandle(ev, storageUnit, kPrintInfoProp, kPrintType, (FW_PlatformHandle)fMacPrintRec);
  443. #endif
  444. }
  445.  
  446. //----------------------------------------------------------------------------------------
  447. // FW_CPrintInfo::GetCopyCount
  448. //----------------------------------------------------------------------------------------
  449.  
  450. void FW_CPrintInfo::GetCopyCount(short& copyCount, FW_Boolean& collate) const
  451. {
  452. #ifdef FW_SUPPORT_GX
  453.     if (fGXJob != NULL)
  454.     {
  455.         copyCount = 1;
  456.         collate   = FALSE;
  457.         return;
  458.     }
  459. #endif
  460. #ifdef FW_BUILD_WIN
  461.     copyCount    = fWinPrintDlg.nCopies;
  462.     collate        = (fWinPrintDlg.Flags & PD_COLLATE) != 0;
  463. #endif
  464. #ifdef FW_BUILD_MAC
  465.     copyCount    = (*fMacPrintRec)->prJob.iCopies;
  466.     collate        = FALSE;
  467. #endif
  468. }
  469.  
  470. //----------------------------------------------------------------------------------------
  471. // FW_CPrintInfo::GetPages
  472. //----------------------------------------------------------------------------------------
  473.  
  474. void FW_CPrintInfo::GetPages(long& firstPage, long& lastPage)
  475. {
  476. #ifdef FW_SUPPORT_GX
  477.     if (fGXJob != NULL)
  478.     {
  479.         ::GXGetJobPageRange(fGXJob, &firstPage, &lastPage);
  480.         return;
  481.     }
  482. #endif
  483. #ifdef FW_BUILD_WIN
  484.     firstPage    = fWinPrintDlg.nFromPage;
  485.     lastPage    = fWinPrintDlg.nToPage;
  486. #endif
  487. #ifdef FW_BUILD_MAC
  488.     firstPage    = (*fMacPrintRec)->prJob.iFstPage;
  489.     lastPage    = (*fMacPrintRec)->prJob.iLstPage;
  490. #endif
  491. }
  492.  
  493. //----------------------------------------------------------------------------------------
  494. // FW_CPrintInfo::GetPageBounds
  495. //----------------------------------------------------------------------------------------
  496.  
  497. FW_CRect FW_CPrintInfo::GetPageBounds() const
  498. {
  499. #ifdef FW_SUPPORT_GX
  500.     if (fGXJob != NULL)
  501.     {
  502.         gxFormat format = ::GXGetJobFormat(fGXJob, 1);
  503.         gxRectangle pageBounds, paperBounds;
  504.         ::GXGetFormatDimensions(format, &pageBounds, &paperBounds);
  505.         
  506.         return FW_CRect(
  507.             FW_ODFixedToFixed(pageBounds.left),
  508.             FW_ODFixedToFixed(pageBounds.top),
  509.             FW_ODFixedToFixed(pageBounds.right),
  510.             FW_ODFixedToFixed(pageBounds.bottom));
  511.     }
  512. #endif
  513. #ifdef FW_BUILD_WIN
  514.     // Scale the bounds
  515.     FW_CPoint resPrint(
  516.         FW_IntToFixed(::GetDeviceCaps(fWinPrintDlg.hDC, LOGPIXELSX)),
  517.         FW_IntToFixed(::GetDeviceCaps(fWinPrintDlg.hDC, LOGPIXELSY)));
  518.  
  519.     FW_CRect pageBounds = fWinPageBounds;
  520.  
  521.     pageBounds.left        = FW_WideMultiply(pageBounds.left,        FW_kFixed72) / resPrint.x;
  522.     pageBounds.top        = FW_WideMultiply(pageBounds.top,        FW_kFixed72) / resPrint.y;
  523.     pageBounds.right    = FW_WideMultiply(pageBounds.right,        FW_kFixed72) / resPrint.x;
  524.     pageBounds.bottom    = FW_WideMultiply(pageBounds.bottom,    FW_kFixed72) / resPrint.y;
  525.  
  526.     return pageBounds;
  527. #endif
  528. #ifdef FW_BUILD_MAC
  529.     return (*fMacPrintRec)->prInfo.rPage;
  530. #endif
  531. }
  532.  
  533. #ifdef FW_BUILD_WIN
  534. //----------------------------------------------------------------------------------------
  535. // FW_CPrintInfo::GetGXJob
  536. //----------------------------------------------------------------------------------------
  537.  
  538. LPPRINTDLG FW_CPrintInfo::WinGetPrintDlg()
  539. {
  540.     return &fWinPrintDlg;
  541. }
  542. #endif
  543.  
  544. #ifdef FW_BUILD_WIN
  545. //----------------------------------------------------------------------------------------
  546. // FW_CPrintInfo::GetGXJob
  547. //----------------------------------------------------------------------------------------
  548.  
  549. void FW_CPrintInfo::WinUpdatePageRect()
  550. {
  551.     FW_ASSERT(fWinPrintDlg.hDC != NULL);
  552.     ::GetClipBox(fWinPrintDlg.hDC, &fWinPageBounds);
  553. }
  554. #endif
  555.  
  556. #ifdef FW_SUPPORT_GX
  557. //----------------------------------------------------------------------------------------
  558. // FW_CPrintInfo::GetGXJob
  559. //----------------------------------------------------------------------------------------
  560.  
  561. gxJob FW_CPrintInfo::GetGXJob() const
  562. {
  563.     return fGXJob;
  564. }
  565. #endif
  566.  
  567. #ifdef FW_BUILD_MAC
  568. //----------------------------------------------------------------------------------------
  569. // FW_CPrintInfo::MacGetTHPrint
  570. //----------------------------------------------------------------------------------------
  571.  
  572. THPrint FW_CPrintInfo::MacGetTHPrint() const
  573. {
  574.     return fMacPrintRec;
  575. }
  576. #endif
  577.  
  578. //========================================================================================
  579. // class FW_CPrintJob
  580. //========================================================================================
  581.  
  582. //----------------------------------------------------------------------------------------
  583. // FW_CPrintJob::FW_CPrintJob
  584. //----------------------------------------------------------------------------------------
  585.  
  586. FW_CPrintJob::FW_CPrintJob(
  587.         FW_CPrintInfo*            printInfo,
  588.         FW_CPrintHandler*        printHandler,
  589.         FW_CPrintEnvironment*    printEnv) :
  590.     fPrintInfo(printInfo),
  591.     fPrintHandler(printHandler),
  592.     fPrintEnv(printEnv)
  593. {
  594. #ifdef FW_SUPPORT_GX
  595.     fGXViewPort            = NULL;
  596.     fGXSpoolUPP            = NULL;
  597.     fMacCanvasWindow    = NULL;
  598. #endif
  599. #ifdef FW_BUILD_WIN
  600.     fWinSaveDCIndex        = 0;
  601. #endif
  602. #ifdef FW_BUILD_MAC
  603.     fMacPrPort            = NULL;
  604. #endif
  605. }
  606.  
  607. //----------------------------------------------------------------------------------------
  608. // FW_CPrintJob::~FW_CPrintJob
  609. //----------------------------------------------------------------------------------------
  610.  
  611. FW_CPrintJob::~FW_CPrintJob()
  612. {
  613. #ifdef FW_SUPPORT_GX
  614.     FW_ASSERT(fGXViewPort == NULL);
  615. #endif
  616. #ifdef FW_BUILD_MAC
  617.     FW_ASSERT(fMacPrPort == NULL);
  618. #endif
  619. }
  620.  
  621. //----------------------------------------------------------------------------------------
  622. // FW_CPrintJob::OpenDocument
  623. //----------------------------------------------------------------------------------------
  624.  
  625. ODFacet* FW_CPrintJob::OpenDocument(
  626.     Environment*        ev,
  627.     ODFrame*            frame,
  628.     ODSession*            session,
  629.     long                numPages,
  630.     const FW_CString&    title)
  631. {
  632.     FW_ASSERT(numPages > 0);
  633.     
  634.     ODFacet* facet = NULL;
  635.     
  636.     // Create a progress dialog
  637.     fPrintHandler->CreateProgressDialog(ev, frame, numPages, title);
  638.  
  639.     FW_TRY
  640.     {
  641.         // Create the platform print job
  642.         PrivCreatePlatformPrintJob(numPages, title);
  643.  
  644.         FW_TRY
  645.         {
  646.             // Get the transform and shape for the page facet
  647.             FW_CRect                pageBounds    = fPrintInfo->GetPageBounds();
  648.             FW_CAcquiredODTransform    aqTransform    = frame->CreateTransform(ev);
  649.             FW_CAcquiredODShape        aqClipShape    = frame->CreateShape(ev);
  650.  
  651.             aqClipShape->SetRectangle(ev, (ODRect*) &pageBounds);
  652.  
  653.             // Create a facet with this geometry
  654.             facet = session->GetWindowState(ev)->
  655.                                         CreateFacet(ev, frame, aqClipShape,
  656.                                                 aqTransform, kODNULL, kODNULL);
  657.             FW_ASSERT(facet != NULL);
  658.  
  659.             FW_TRY
  660.             {
  661.                 // Create an OpenDoc canvas
  662.                 ODCanvas* canvas = PrivCreatePrintCanvas(ev, facet);
  663.                 FW_ASSERT(canvas != NULL);
  664.  
  665.                 // Set its owner
  666.                 FW_CAcquiredODPart aqPart = frame->AcquirePart(ev);
  667.                 canvas->SetOwner(ev, aqPart);
  668.  
  669.                 FW_TRY
  670.                 {
  671.                     // Attach the canvas to the facet
  672.                     facet->ChangeCanvas(ev, canvas);
  673.  
  674.                     FW_TRY
  675.                     {
  676.                         // Add the facet to the frame
  677.                         frame->FacetAdded(ev, facet);
  678.                     }
  679.                     FW_CATCH_BEGIN
  680.                     FW_CATCH_EVERYTHING()
  681.                     {
  682.                         // If the canvas has already been attached to the facet, then
  683.                         // we need to delete the facet first to prevent the facet from
  684.                         // referencing a canvas that has been deleted
  685.                         delete facet;
  686.                         facet = NULL;
  687.                         delete canvas;
  688.                         canvas = NULL;
  689.                         FW_THROW_SAME();
  690.                     }
  691.                     FW_CATCH_END
  692.                 }
  693.                 FW_CATCH_BEGIN
  694.                 FW_CATCH_EVERYTHING()
  695.                 {
  696.                     delete canvas;
  697.                     FW_THROW_SAME();
  698.                 }
  699.                 FW_CATCH_END
  700.             }
  701.             FW_CATCH_BEGIN
  702.             FW_CATCH_EVERYTHING()
  703.             {
  704.                 delete facet;
  705.                 FW_THROW_SAME();
  706.             }
  707.             FW_CATCH_END
  708.         }
  709.         FW_CATCH_BEGIN
  710.         FW_CATCH_EVERYTHING()
  711.         {
  712.             PrivAbortPlatformPrintJob();
  713.             FW_THROW_SAME();
  714.         }
  715.         FW_CATCH_END
  716.     }
  717.     FW_CATCH_BEGIN
  718.     FW_CATCH_EVERYTHING()
  719.     {
  720.         fPrintHandler->DestroyProgressDialog(ev, frame);
  721.  
  722.         FW_THROW_SAME();
  723.     }
  724.     FW_CATCH_END
  725.  
  726.     return facet;
  727. }
  728.  
  729. //----------------------------------------------------------------------------------------
  730. // FW_CPrintJob::PrivCreatePlatformPrintJob
  731. //----------------------------------------------------------------------------------------
  732.  
  733. void FW_CPrintJob::PrivCreatePlatformPrintJob(long    numPages, const FW_CString&    title)
  734. {
  735. #ifdef FW_SUPPORT_GX
  736.     gxJob job = fPrintInfo->GetGXJob();
  737.     if (job != NULL)
  738.     {
  739.         Str255 pascalTitle;
  740.         title.ExportPascal(pascalTitle);
  741.     
  742.         ::GXStartJob(job, pascalTitle, numPages);
  743.         FW_XPrint::CheckGXJobError(job);
  744.         
  745.         return;
  746.     }
  747. #endif
  748.  
  749. #ifdef FW_BUILD_WIN
  750.     DOCINFO di;
  751.  
  752.     di.cbSize        = sizeof(DOCINFO);
  753.     di.lpszDocName    = title;
  754.     di.lpszOutput    = NULL;
  755.     di.lpszDatatype    = NULL;
  756.     di.fwType        = 0;
  757.  
  758.     LPPRINTDLG lppd = fPrintInfo->WinGetPrintDlg();
  759.     FW_ASSERT(lppd->hDC != NULL);
  760.     FW_XPrint::CheckPrintError(::StartDoc(lppd->hDC, &di));
  761. #endif
  762.  
  763. #ifdef FW_BUILD_MAC
  764.     fPrintEnv->MacRestoreResFile();
  765.  
  766.     THPrint thPrint = fPrintInfo->MacGetTHPrint();
  767.     ::PrValidate(thPrint);    // Set document name
  768.  
  769.     {
  770.         FW_ASSERT(fMacPrPort == NULL);
  771.         FW_CMacTempPort tempPort;
  772.  
  773.         fMacPrPort = ::PrOpenDoc(thPrint, NULL, NULL);
  774.         FW_XPrint::MacCheckPrintError();
  775.         FW_ASSERT(fMacPrPort != NULL);
  776.     }
  777. #endif
  778. }
  779.  
  780. //----------------------------------------------------------------------------------------
  781. // FW_CPrintJob::PrivAbortPlatformPrintJob
  782. //----------------------------------------------------------------------------------------
  783.  
  784. void FW_CPrintJob::PrivAbortPlatformPrintJob()
  785. {
  786. #ifdef FW_SUPPORT_GX
  787.     gxJob job = fPrintInfo->GetGXJob();
  788.     if (job != NULL)
  789.     {
  790.         // Clean up QD -> GX spooling structures
  791.         ::DisposeWindow(fMacCanvasWindow);
  792.         fMacCanvasWindow = NULL;
  793.  
  794.         DisposeRoutineDescriptor(fGXSpoolUPP);
  795.         
  796.         ::GXSetJobError(job, gxPrUserAbortErr);
  797.         ::GXFinishJob(job);
  798.         ::GXDisposeViewPort(fGXViewPort);
  799.         fGXViewPort = NULL;
  800.         
  801.         return;
  802.     }
  803. #endif
  804. #ifdef FW_BUILD_WIN
  805.     LPPRINTDLG lppd = fPrintInfo->WinGetPrintDlg();
  806.     FW_ASSERT(lppd->hDC != NULL);
  807.  
  808.     // Abort the print job
  809.     int error = ::AbortDoc(lppd->hDC);
  810.     ::DeleteDC(lppd->hDC);
  811.     lppd->hDC = NULL;
  812. #endif
  813. #ifdef FW_BUILD_MAC
  814.     FW_ASSERT(fMacPrPort != NULL);
  815.     FW_CMacTempPort tempPort = (GrafPtr) fMacPrPort;
  816.  
  817.     fPrintEnv->MacRestoreResFile();
  818.  
  819.     ::PrSetError(iPrAbort);
  820.     ::PrCloseDoc(fMacPrPort);
  821.     fMacPrPort = NULL;
  822. #endif
  823. }
  824.  
  825. //----------------------------------------------------------------------------------------
  826. // FW_CPrintJob::PrivCreatePrintCanvas
  827. //----------------------------------------------------------------------------------------
  828.  
  829. ODCanvas* FW_CPrintJob::PrivCreatePrintCanvas(Environment* ev, ODFacet* facet)
  830. {
  831.     ODCanvas* canvas;
  832.  
  833. #ifdef FW_SUPPORT_GX
  834.     gxJob job = fPrintInfo->GetGXJob();
  835.     if (job != NULL)
  836.     {
  837.         fGXViewPort = ::GXNewViewPort(gxScreenViewDevices);
  838.  
  839.         // DTC -- Coercing fGXViewPort distresses the compier since gxViewPort is a pointer
  840.         // to a partially defined struct.  This is OK, the Apple headers partially define
  841.         // it in order to prevent direct access.
  842. #if (defined __SC__ || defined __MRC__) && !defined _WINDOWS
  843. #pragma options(!warn_cast_incomplete_type)    // pragma will be in effect for remainder of function
  844. #endif
  845.         canvas = facet->CreateCanvas(ev, kODQuickDrawGX,
  846.                                 (ODPlatformCanvas) fGXViewPort, kODFalse, kODFalse);
  847.         FW_ASSERT(canvas != NULL);
  848.     
  849.         gxJob job = fPrintInfo->GetGXJob();
  850.         FW_ASSERT(job != NULL);
  851.         canvas->SetPlatformPrintJob(ev, kODQuickDrawGX, job);
  852.     
  853.         // Create a new QuickDraw window to draw to
  854.         FW_CPlatformRect boundsWindow = fPrintInfo->GetPageBounds();
  855.         fMacCanvasWindow = ::NewCWindow(NULL, &boundsWindow, "\p", FALSE,
  856.             documentProc, NULL, FALSE, 0l);
  857.     
  858.         // Create a UPP for the spool proc
  859.         fGXSpoolUPP = NewgxShapeSpoolProc(MacGXSpoolProc);
  860.     
  861.         // Set the QuickDraw canvas in the OD Canvas
  862.         canvas->SetPlatformCanvas(ev, kODQuickDraw, fMacCanvasWindow);
  863.         return canvas;
  864.     }
  865. #endif
  866.  
  867. #ifdef FW_BUILD_WIN
  868.     LPPRINTDLG lppd = fPrintInfo->WinGetPrintDlg();
  869.     canvas = facet->CreateCanvas(ev, kODWindows,
  870.                                 lppd->hDC, kODFalse, kODFalse);
  871.     canvas->SetPlatformPrintJob(ev, kODWindows, lppd);
  872. #endif
  873. #ifdef FW_BUILD_MAC
  874.     canvas = facet->CreateCanvas(ev, kODQuickDraw,
  875.                                 (ODPlatformCanvas) fMacPrPort, kODFalse, kODFalse);
  876.  
  877.     THPrint thPrint = fPrintInfo->MacGetTHPrint();
  878.     FW_ASSERT(thPrint != NULL);
  879.  
  880.     canvas->SetPlatformPrintJob(ev, kODQuickDraw, thPrint);
  881. #endif
  882.  
  883.     return canvas;
  884. }
  885.  
  886. //----------------------------------------------------------------------------------------
  887. // FW_CPrintJob::CloseDocument
  888. //----------------------------------------------------------------------------------------
  889.  
  890. void FW_CPrintJob::CloseDocument(
  891.     Environment*        ev,
  892.     ODFacet*            facet)
  893. {
  894.     DoCloseDocument(ev, facet, TRUE);
  895. }
  896.  
  897. //----------------------------------------------------------------------------------------
  898. // FW_CPrintJob::CloseDocumentOnError
  899. //----------------------------------------------------------------------------------------
  900.  
  901. void FW_CPrintJob::CloseDocumentOnError(
  902.     Environment*        ev,
  903.     ODFacet*            facet)
  904. {
  905.     DoCloseDocument(ev, facet, FALSE);
  906. }
  907.  
  908. //----------------------------------------------------------------------------------------
  909. // FW_CPrintJob::OpenPage
  910. //----------------------------------------------------------------------------------------
  911.  
  912. void FW_CPrintJob::OpenPage(long pageNumber)
  913. {
  914.     FW_ASSERT(pageNumber > 0);
  915.  
  916. #ifdef FW_SUPPORT_GX
  917.     gxJob job = fPrintInfo->GetGXJob();
  918.     if (job != NULL)
  919.     {
  920.         // Start a new page
  921.         ::GXStartPage(job, pageNumber, ::GXGetJobFormat(job, 1), 1, &fGXViewPort);
  922.         FW_XPrint::CheckGXJobError(job);
  923.  
  924.         // Install QuickDraw -> QuickDraw GX translator
  925.         gMacGXSpool.fGXViewPort = fGXViewPort;
  926.         gMacGXSpool.fGXPrintJob = job;
  927.         gMacGXSpool.fPageBounds = fPrintInfo->GetPageBounds();
  928.  
  929.         FW_CPlatformRect    pageRect = gMacGXSpool.fPageBounds;
  930.         FW_CPlatformPoint    styleStretch(1, 1);
  931.         
  932.         FW_ASSERT(fMacCanvasWindow != NULL);
  933.         FW_ASSERT(fGXSpoolUPP != NULL);
  934.  
  935.         ::GXInstallQDTranslator(fMacCanvasWindow,
  936.                               gxDefaultOptionsTranslation,
  937.                               &pageRect, &pageRect,
  938.                               styleStretch, 
  939.                               fGXSpoolUPP,
  940.                               NULL);
  941.  
  942.         return;
  943.     }
  944. #endif
  945. #ifdef FW_BUILD_WIN
  946.     LPPRINTDLG lppd = fPrintInfo->WinGetPrintDlg();
  947.     FW_ASSERT(lppd->hDC != NULL);
  948.     FW_XPrint::CheckPrintError(::StartPage(lppd->hDC));
  949.  
  950.     // Restore the DC
  951.     if (fWinSaveDCIndex != 0)
  952.     {
  953.         ::RestoreDC(lppd->hDC, fWinSaveDCIndex);
  954.         fWinSaveDCIndex = 0;
  955.     }
  956. #endif
  957. #ifdef FW_BUILD_MAC
  958.     {
  959.         FW_ASSERT(fMacPrPort != NULL);
  960.         FW_CMacTempPort tempPort = (GrafPtr) fMacPrPort;
  961.  
  962.         fPrintEnv->MacRestoreResFile();
  963.  
  964.         ::PrOpenPage(fMacPrPort, NULL);
  965.  
  966.         FW_XPrint::MacCheckPrintError();
  967.     }
  968. #endif
  969.  
  970.     // Show current page number
  971.     fPrintHandler->UpdateProgressDialog(pageNumber);
  972. }
  973.  
  974. //----------------------------------------------------------------------------------------
  975. // FW_CPrintJob::ClosePage
  976. //----------------------------------------------------------------------------------------
  977.  
  978. void FW_CPrintJob::ClosePage()
  979. {
  980.     DoClosePage(TRUE);
  981. }
  982.  
  983. //----------------------------------------------------------------------------------------
  984. // FW_CPrintJob::ClosePageOnError
  985. //----------------------------------------------------------------------------------------
  986.  
  987. void FW_CPrintJob::ClosePageOnError()
  988. {
  989.     DoClosePage(FALSE);
  990. }
  991.  
  992. //----------------------------------------------------------------------------------------
  993. // FW_CPrintJob::FinishPrinting
  994. //----------------------------------------------------------------------------------------
  995.  
  996. void FW_CPrintJob::FinishPrinting()
  997. {
  998. #ifdef FW_SUPPORT_GX
  999.     gxJob job = fPrintInfo->GetGXJob();
  1000.     if (job != NULL)
  1001.         return;
  1002. #endif
  1003.  
  1004. #ifdef FW_BUILD_MAC
  1005.     FW_ASSERT(fMacPrPort == NULL);
  1006.  
  1007.     THPrint thPrint = fPrintInfo->MacGetTHPrint();
  1008.     if ((*thPrint)->prJob.bJDocLoop == bSpoolLoop)
  1009.     {
  1010.         TPrStatus printStatus;
  1011.         ::PrPicFile(thPrint, NULL, NULL, NULL, &printStatus);
  1012.     }
  1013. #endif
  1014. }
  1015.  
  1016. //----------------------------------------------------------------------------------------
  1017. // FW_CPrintJob::DoCloseDocument
  1018. //----------------------------------------------------------------------------------------
  1019.  
  1020. void FW_CPrintJob::DoCloseDocument(
  1021.             Environment*        ev,
  1022.             ODFacet*            facet,
  1023.             FW_Boolean            checkErrors)
  1024. {
  1025.     ODCanvas* canvas = facet->GetCanvas(ev);
  1026.     ODFrame* frame = facet->GetFrame(ev);
  1027.  
  1028.     frame->FacetRemoved(ev, facet);
  1029.     delete canvas;
  1030.     delete facet;
  1031.  
  1032.     FW_TRY
  1033.     {
  1034. #ifdef FW_SUPPORT_GX
  1035.         gxJob job = fPrintInfo->GetGXJob();
  1036.         if (job != NULL)
  1037.         {
  1038.             // Finish the job
  1039.             ::GXFinishJob(job);
  1040.  
  1041.             // Clean up QD -> GX spooling structures
  1042.             ::DisposeWindow(fMacCanvasWindow);
  1043.             fMacCanvasWindow = NULL;
  1044.             DisposeRoutineDescriptor(fGXSpoolUPP);
  1045.  
  1046.             // Dispose the viewport
  1047.             ::GXDisposeViewPort(fGXViewPort);
  1048.             fGXViewPort = NULL;
  1049.  
  1050.             if (checkErrors)
  1051.                 FW_XPrint::CheckGXJobError(job);
  1052.         }
  1053.         else
  1054. #endif
  1055.         {
  1056. #ifdef FW_BUILD_WIN
  1057.             LPPRINTDLG lppd = fPrintInfo->WinGetPrintDlg();
  1058.             FW_ASSERT(lppd->hDC != NULL);
  1059.         
  1060.             // Finish the print job
  1061.             int error = ::EndDoc(lppd->hDC);
  1062.             ::DeleteDC(lppd->hDC);
  1063.             lppd->hDC = NULL;
  1064.             if (checkErrors)
  1065.                 FW_XPrint::CheckPrintError(error);
  1066. #endif
  1067. #ifdef FW_BUILD_MAC
  1068.             fPrintEnv->MacRestoreResFile();
  1069.             
  1070.             {    
  1071.                 FW_ASSERT(fMacPrPort != NULL);
  1072.                 FW_CMacTempPort tempPort = (GrafPtr) fMacPrPort;
  1073.                 
  1074.                 ::PrCloseDoc(fMacPrPort);
  1075.                 fMacPrPort = NULL;
  1076.             }
  1077.         
  1078.             if (checkErrors)
  1079.                 FW_XPrint::MacCheckPrintError();
  1080. #endif
  1081.         }
  1082.     }
  1083.     FW_CATCH_BEGIN
  1084.     FW_CATCH_EVERYTHING()
  1085.     {
  1086.         // Close the progress dialog
  1087.         fPrintHandler->DestroyProgressDialog(ev, frame);
  1088.         FW_THROW_SAME();
  1089.     }
  1090.     FW_CATCH_END
  1091.  
  1092.     // Close the progress dialog
  1093.     fPrintHandler->DestroyProgressDialog(ev, frame);
  1094. }
  1095.  
  1096. //----------------------------------------------------------------------------------------
  1097. // FW_CPrintJob::DoClosePage
  1098. //----------------------------------------------------------------------------------------
  1099.  
  1100. void FW_CPrintJob::DoClosePage(
  1101.             FW_Boolean            checkErrors)
  1102. {
  1103. #ifdef FW_SUPPORT_GX
  1104.     gxJob job = fPrintInfo->GetGXJob();
  1105.     if (job != NULL)
  1106.     {
  1107.         // Remove the QD->GX translator; this flushes the GX shape queue
  1108.         gxTranslationStatistic statistic;
  1109.         ::GXRemoveQDTranslator(fMacCanvasWindow, &statistic);
  1110.  
  1111.         // Finish the page
  1112.         ::GXFinishPage(job);
  1113.  
  1114.         if (checkErrors)
  1115.             FW_XPrint::CheckGXJobError(job);
  1116.  
  1117.         return;
  1118.     }
  1119. #endif
  1120. #ifdef FW_BUILD_WIN
  1121.     LPPRINTDLG lppd = fPrintInfo->WinGetPrintDlg();
  1122.     FW_ASSERT(lppd->hDC != NULL);
  1123.  
  1124.     // Save the DC so it can be restored at the start of next page
  1125.     fWinSaveDCIndex = ::SaveDC(lppd->hDC);
  1126.  
  1127.     int error = ::EndPage(lppd->hDC);
  1128.     if (checkErrors)
  1129.         FW_XPrint::CheckPrintError(error);
  1130. #endif
  1131. #ifdef FW_BUILD_MAC
  1132.     {
  1133.         FW_ASSERT(fMacPrPort != NULL);
  1134.         FW_CMacTempPort tempPort = (GrafPtr) fMacPrPort;
  1135.  
  1136.         fPrintEnv->MacRestoreResFile();
  1137.  
  1138.         ::PrClosePage(fMacPrPort);
  1139.     }
  1140.  
  1141.     if (checkErrors)
  1142.         FW_XPrint::MacCheckPrintError();
  1143. #endif
  1144. }
  1145.  
  1146. //----------------------------------------------------------------------------------------
  1147. // FW_XPrint::CheckPrintError
  1148. //----------------------------------------------------------------------------------------
  1149.  
  1150. void FW_XPrint::CheckPrintError(FW_PlatformError error)
  1151. {
  1152. #ifdef FW_SUPPORT_GX
  1153.     if (error == gxPrUserAbortErr)
  1154.         FW_Failure(FW_xPrintingCanceled);
  1155. #endif
  1156. #ifdef FW_BUILD_WIN
  1157.     if (error == SP_USERABORT)
  1158.         FW_Failure(FW_xPrintingCanceled);
  1159.  
  1160.     if (error < 0)
  1161.         FW_Failure(error);
  1162. #endif
  1163. #ifdef FW_BUILD_MAC
  1164.     if (error == iPrAbort)
  1165.         FW_Failure(FW_xPrintingCanceled);
  1166.  
  1167.     if(error != 0)
  1168.         FW_Failure(error);
  1169. #endif
  1170. }
  1171.  
  1172. #ifdef FW_SUPPORT_GX
  1173. //----------------------------------------------------------------------------------------
  1174. // FW_XPrint::CheckGXJobError
  1175. //----------------------------------------------------------------------------------------
  1176.  
  1177. void FW_XPrint::CheckGXJobError(gxJob job)
  1178. {
  1179.     CheckPrintError(::GXGetJobError(job));
  1180. }
  1181. #endif
  1182.  
  1183. #ifdef FW_BUILD_MAC
  1184. //----------------------------------------------------------------------------------------
  1185. // FW_XPrint::MacCheckPrintError
  1186. //----------------------------------------------------------------------------------------
  1187.  
  1188. void FW_XPrint::MacCheckPrintError()
  1189. {
  1190.     short error = ::PrError();
  1191.     CheckPrintError(error);
  1192. }
  1193. #endif
  1194.  
  1195. #if defined(FW_SUPPORT_GX) && defined(FW_BUILD_MAC)
  1196.  
  1197. //----------------------------------------------------------------------------------------
  1198. // MacGXSpoolProc
  1199. //----------------------------------------------------------------------------------------
  1200.  
  1201. OSErr    MacGXSpoolProc(gxShape shape, long /* refCon */)
  1202. {
  1203.     gxShapeType        shapeType = ::GXGetShapeType(shape);
  1204.     
  1205.     if (shapeType == gxEmptyType   || 
  1206.         shapeType == gxFullType    || 
  1207.         shapeType == gxPictureType ||
  1208.         ::GXTouchesBoundsShape((gxRectangle*)&gMacGXSpool.fPageBounds, shape))
  1209.     {
  1210.         ::GXSetShapeViewPorts(shape, 1, &gMacGXSpool.fGXViewPort);
  1211.         ::GXDrawShape(shape);
  1212.         ::GXSetShapeViewPorts(shape, 0, NULL);
  1213.     }
  1214.  
  1215.     return (OSErr) ::GXGetGraphicsError(NULL);
  1216. }
  1217. #endif
  1218.  
  1219. //----------------------------------------------------------------------------------------
  1220. // SaveHandle
  1221. //----------------------------------------------------------------------------------------
  1222.  
  1223. void    SaveHandle(
  1224.             Environment*         ev,
  1225.             ODStorageUnit*         storageUnit,
  1226.             const char*            propName,
  1227.             const char*            propType,
  1228.             FW_PlatformHandle    handle)
  1229. {
  1230.     if (handle == NULL)
  1231.     {
  1232.         if (storageUnit->Exists(ev, (ODType) propName, (ODType) propType, 0))
  1233.         {
  1234.             storageUnit->Focus(ev, (ODType) propName, kODPosUndefined, (ODType) propType, 0, kODPosUndefined);
  1235.             storageUnit->Remove(ev);
  1236.         }
  1237.     }
  1238.     else
  1239.     {
  1240.         FW_CAcquireLockedSystemHandle lock(handle);
  1241.     
  1242.         void* buffer             = lock.GetPointer();
  1243.         unsigned long bufSize    = FW_CMemoryManager::GetSystemHandleSize(handle);
  1244.     
  1245.         ::SaveBuffer(ev, storageUnit, propName, propType, buffer, bufSize);
  1246.     }
  1247. }
  1248.             
  1249. //----------------------------------------------------------------------------------------
  1250. // SaveBuffer
  1251. //----------------------------------------------------------------------------------------
  1252.  
  1253. void    SaveBuffer(
  1254.             Environment*         ev,
  1255.             ODStorageUnit*         storageUnit,
  1256.             const char*            propName,
  1257.             const char*            propType,
  1258.             const void*            buffer,
  1259.             unsigned long        bufSize)
  1260. {
  1261.     if (storageUnit->Exists(ev, (ODType) propName, (ODType) propType, 0))
  1262.         storageUnit->Focus(ev, (ODType) propName, kODPosUndefined, (ODType) propType, 0, kODPosUndefined);
  1263.     else
  1264.         storageUnit->AddProperty(ev, (ODType) propName)->AddValue(ev, (ODType) propType);
  1265.  
  1266.     unsigned long oldSize = storageUnit->GetSize(ev);
  1267.  
  1268.     storageUnit->SetOffset(ev, 0);
  1269.  
  1270.     FW_CByteArray byteArray(buffer, bufSize);
  1271.     storageUnit->SetValue(ev, byteArray);
  1272.  
  1273.     if (oldSize > bufSize)
  1274.         storageUnit->DeleteValue(ev, oldSize - bufSize);
  1275. }
  1276.  
  1277. //----------------------------------------------------------------------------------------
  1278. // LoadHandle
  1279. //----------------------------------------------------------------------------------------
  1280.  
  1281. FW_Boolean LoadHandle(
  1282.             Environment*         ev,
  1283.             ODStorageUnit*         storageUnit,
  1284.             const char*            propName,
  1285.             const char*            propType,
  1286.             FW_PlatformHandle&    handle)
  1287. {
  1288.     if (storageUnit->Exists(ev, (ODType) propName, (ODType) propType, 0))
  1289.     {
  1290.         storageUnit->Focus(ev, (ODType) propName, kODPosUndefined, (ODType) propType, 0, kODPosUndefined);
  1291.         unsigned long size = storageUnit->GetSize(ev);
  1292.         FW_CAcquireTemporarySystemHandle tempHandle(size);
  1293.         void* buffer = tempHandle.GetPointer();
  1294.         
  1295.         unsigned long sizeLoaded = 0;
  1296.         if (::LoadBuffer(ev, storageUnit, propName, propType, buffer, sizeLoaded))
  1297.         {
  1298.             handle = tempHandle.GetPlatformHandle();
  1299.             tempHandle.Orphan();
  1300.             return TRUE;
  1301.         }
  1302.     }
  1303.  
  1304.     return FALSE;
  1305. }
  1306.  
  1307. //----------------------------------------------------------------------------------------
  1308. // LoadBuffer
  1309. //----------------------------------------------------------------------------------------
  1310.  
  1311. FW_Boolean     LoadBuffer(
  1312.             Environment*         ev,
  1313.             ODStorageUnit*         storageUnit,
  1314.             const char*            propName,
  1315.             const char*            propType,
  1316.             void*                buffer,
  1317.             unsigned long&        bufSize)
  1318. {
  1319.     if (storageUnit->Exists(ev, (ODType) propName, (ODType) propType, 0))
  1320.     {
  1321.         storageUnit->Focus(ev, (ODType) propName, kODPosUndefined, (ODType) propType, 0, kODPosUndefined);
  1322.         storageUnit->SetOffset(ev, 0);
  1323.  
  1324.         bufSize = storageUnit->GetSize(ev);
  1325.     
  1326. #if FW_OPENDOC_VERSION >= FW_OPENDOC_DR3
  1327.         FW_CByteArray byteArray;
  1328.         storageUnit->GetValue(ev, bufSize, byteArray);
  1329.         byteArray.CopyBuffer(buffer, bufSize);
  1330. #else
  1331.         FW_CByteArray byteArray(buffer, bufSize);
  1332.         storageUnit->GetValue(ev, byteArray);
  1333. #endif
  1334.  
  1335.         return TRUE;
  1336.     }
  1337.     
  1338.     return FALSE;
  1339. }
  1340.  
  1341.